#ifndef __VEC2_H__
#define __VEC2_H__

#include "stdafx.h"
#include "Logger.h"

namespace GeorgeLib
{
	/// @brief Holds 2 values and does vector maths.

	/// @details Contains values for the a 2D vector, has functions for 
	///			vector calculations, and various other operator overloads.

	class DLLEXPORT vec2
	{
	public:
		float	x, ///< value on the x-axis
			y; ///< value on the y-axis

	public:

		/// constructor : an empty vector, (0,0)
		vec2(void);

		/// constructor : from three values, (x,y)
		vec2(float X, float Y);

		/// constructor : from one value, (a,a,a)
		/** @param a a floating point value to fill the vector
		*/
		vec2(float a);

		/// constructor : from an array of float[2]
		/** @param v an float array of 2
		*/
		vec2(float * v);

		/// copy constructor : from another vector
		vec2(const vec2 &v);

		/// destructor
		~vec2(void);

		/// addition of all the values of the vector
		float	total(void);

		/// negative of this vector
		vec2	negated(void);

		/// values of this vector to an array
		/** @param[out] arr an array to copy values to
		*/
		void	asArray(float *arr);

		/// magnitude of this vector
		float	magnitude(void);

		/// magnitude squared of this vector
		float	magnitudeSqr(void);

		/// unit vector of this vector
		vec2	normal(void);

		/// angles between (1,1) and this vector on each axis in degrees
		vec2	direction(void);

		/// distance between this vector and v
		float	distancebetween(vec2 v);

		/// angle between this vector and v
		float	anglebetween(vec2 v);

		/// dot product between this vector and v
		float	dotproduct(vec2 v);

		/// rotate this vector about an arbitrary axis
		/** @param angle the amount in degrees to rotate the vector
		*	@param axis the axis in which to rotate the vector around
		*/
		vec2	rotateabout(float angle, vec2 axis);

		/// add vector v to this vector
		vec2	operator+		(vec2 v);

		/// add vector v to this vector
		void	operator+=		(vec2 v);

		/// subtract vector v from this vector
		vec2	operator-		(vec2 v);

		/// subtract vector v from this vector
		void	operator-=		(vec2 v);

		/// multiply the values in this vector by f
		vec2	operator*		(float f);

		/// multiply the values in this vector by f
		void	operator*=		(float f);

		/// divide the values in this vector by f
		vec2	operator/		(float f);

		/// divide the values in this vector by f
		void	operator/=		(float f);

		/// perform a dot product between this vector and vector v
		float	operator*		(vec2 v);

		/// perform a cross product between this vector and vector v
		vec2	operator^		(vec2 v);

		/// checks if vector is equal to another vector
		bool	operator==		(vec2 v);

		/// checks if vector is not equal to another vector
		bool	operator!=		(vec2 v);

		/// checks if vector magnitude is more than another vector's magnitude
		bool	operator>		(vec2 v);

		/// checks if vector magnitude is more than or equal to another vector's magnitude
		bool	operator>=		(vec2 v);

		/// checks if vector magnitude is less than another vector's magnitude
		bool	operator<		(vec2 v);

		/// checks if vector magnitude is less than or equal to another vector's magnitude
		bool	operator<=		(vec2 v);

		/// change the values of this vector with 2 values using operator()
		void	operator()		(float X, float Y);

		/// change the values of this vector with another vector using operator()
		void	operator()		(vec2 v);

		/// get values using [] operator
		/** @param a a integral value from 0 to 1;
		*	@return the \c x value if \c a is 0, and the \c y value if \c a is 1
		*/
		float	operator[]		(int a);

		/// negative value of vector
		friend	vec2			operator-		(vec2 v);

		/// output vector contents to console
		friend	ostream&		operator<<		(ostream &os, vec2 &v);

		/// round up numbers to 5 digits after the decimal point
		/**	@param v the vector that is to be rounded off
		*	@return the rounded off vector
		*/
		friend	vec2			detectzero(vec2 v);
	};

	typedef const vec2 cvec2;
} /// namespace GeorgeLib

#endif /// __VEC2_H__ ///